<script setup lang="ts">
import { useFuse } from '@vueuse/integrations/useFuse';

import { svgIconComponents } from '@/plugins/icons';
import { useAppearanceSettingStore } from '@/store/modules/appearance-setting';

const emits = defineEmits<{
  (e: 'select', value: string | undefined): void;
}>();

const borderRadius = computed(() => useAppearanceSettingStore().borderRadius);

const pageSize = 25;
const page = ref(1);
const filterPattern = ref('');
const debouncedPattern = useDebounce(filterPattern, 300);

/**
 * 多色图标
 */
const { results: svgIcons } = useFuse<{
  name: string;
  component: Component;
}>(debouncedPattern, markRaw(svgIconComponents), {
  matchAllWhenSearchEmpty: true,
  fuseOptions: {
    isCaseSensitive: false,
    includeMatches: false,
    findAllMatches: false,
    shouldSort: true,
    keys: ['name'],
  },
});
const searchedSvgIcons = computed(() => svgIcons.value.map(result => result.item));
const paginationSvgIcons = computed(() => {
  const start = (page.value - 1) * pageSize;
  return searchedSvgIcons.value.slice(start, start + pageSize);
});

function handleSearch(pattern: string) {
  filterPattern.value = pattern;
  page.value = 1;
}

/**
 * 选择图标
 */
function selectIcon(name: string) {
  const result = `svg__${name}`;
  emits('select', result);
}
</script>

<template>
  <div>
    <div v-if="searchedSvgIcons.length > 0" class="px-2">
      <NInput :value="filterPattern" clearable @update:value="handleSearch" />
      <NGrid x-gap="6" y-gap="6" :cols="Math.sqrt(pageSize)" class="mt-2">
        <NGridItem
          v-for="iconComponent of paginationSvgIcons"
          :key="iconComponent.name"
          @click="selectIcon(iconComponent.name)"
        >
          <div class="flex items-center justify-center cursor-pointer hover-icon">
            <SvgIcon :name="iconComponent.name" :size="24" />
          </div>
        </NGridItem>
      </NGrid>
      <div class="pt-2 flex justify-end">
        <NPagination
          v-model:page="page"
          simple
          :item-count="searchedSvgIcons.length"
          :page-size="pageSize"
        />
      </div>
    </div>

    <div v-else class="py-6">
      <NEmpty size="large" description="暂无图标" />
    </div>
  </div>
</template>

<style scoped lang="less">
.hover-icon {
  padding: 6px;
  border-radius: v-bind(borderRadius);
  &:hover {
    transition: all 0.2s;
    background-color: #f2f2f2;
    transform: scale(1.2);
  }
}
</style>
